package datawave.xmlsync.util;

import org.w3c.dom.Attr;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NamedNodeMap;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import xmlsync2.XMLAPI;


/**
 * @author jinwoo
 *
 * To change this generated comment edit the template variable "typecomment":
 * Window>Preferences>Java>Templates.
 * To enable and disable the creation of type comments go to
 * Window>Preferences>Java>Code Generation.
 */
public class XMLRender {

	protected StringBuffer buffer = null;
	public XMLRender()
	{
	}

	public String text(final Element element)
	{
		buffer = new StringBuffer(1024);
		textdump(element);
		return buffer.toString();
	}

	private void textdump(final Element element)
	{
		Node node = element.getFirstChild();
		while (node != null)
		{
			switch (node.getNodeType())
			{
				case Node.ELEMENT_NODE :
					textdump((Element) node);
					break;
				default :
					buffer.append(node.getNodeValue());
					break;
			}
			node = node.getNextSibling();
		}
	}
	
	public String toString(final Node node)
	{
		buffer = new StringBuffer(1024);
		dump(node);
		return buffer.toString();
	}

	protected void attributes2buffer(final NamedNodeMap list)
	{
		int size = list.getLength();
		if (size > 0)
		{
			for (int i = 0; i < size; i++)
				buffer.append(" ").append(((Attr) list.item(i)).getName()).append("=\"").append(XMLAPI.encode(((Attr) list.item(i)).getValue())).append("\"");
		}
	}
	
	protected void nodelist2buffer(final NodeList list)
	{
		int size = list.getLength();
		if (size > 0)
		{
			for (int i = 0; i < size; i++)
				dump(list.item(i));
		}
	}

	protected void dump(final Node node)
	{
		if (node != null)
		{
			switch (node.getNodeType())
			{
				case Node.ELEMENT_NODE :
					if (node.getFirstChild() == null)
					{
						buffer.append("<").append(node.getNodeName());
						attributes2buffer(node.getAttributes());
						buffer.append("/>");
					}
					else
					{
						buffer.append("<").append(node.getNodeName());
						attributes2buffer(node.getAttributes());
						buffer.append(">");
						nodelist2buffer(node.getChildNodes());
						buffer.append("</").append(node.getNodeName()).append(">");
					}
					break;
				case Node.TEXT_NODE :
					buffer.append(XMLAPI.encode(node.getNodeValue()));
					break;
				case Node.CDATA_SECTION_NODE :
					buffer.append("<![CDATA[").append(node.getNodeValue()).append("]]>");
					break;
				case Node.ENTITY_REFERENCE_NODE :
					buffer.append("&").append(node.getNodeName()).append(";");
					break;
				case Node.DOCUMENT_FRAGMENT_NODE :
					nodelist2buffer(node.getChildNodes());
					break;
				case Node.DOCUMENT_NODE :
					dump(((Document) node).getDocumentElement());
					break;
			}
		}
	}
}
